1   /*                        __    __  __  __    __  ___
2    *                       \  \  /  /    \  \  /  /  __/
3    *                        \  \/  /  /\  \  \/  /  /
4    *                         \____/__/  \__\____/__/.ɪᴏ
5    * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ
6    */
7   package io.vavr.collection;
8   
9   import io.vavr.*;
10  import io.vavr.collection.Stream.Cons;
11  import io.vavr.collection.Stream.Empty;
12  import io.vavr.collection.StreamModule.*;
13  import io.vavr.control.Option;
14  
15  import java.io.*;
16  import java.util.*;
17  import java.util.function.*;
18  import java.util.stream.Collector;
19  
20  import static io.vavr.collection.JavaConverters.ChangePolicy.IMMUTABLE;
21  import static io.vavr.collection.JavaConverters.ChangePolicy.MUTABLE;
22  
23  /**
24   * An immutable {@code Stream} is lazy sequence of elements which may be infinitely long.
25   * Its immutability makes it suitable for concurrent programming.
26   * <p>
27   * A {@code Stream} is composed of a {@code head} element and a lazy evaluated {@code tail} {@code Stream}.
28   * <p>
29   * There are two implementations of the {@code Stream} interface:
30   *
31   * <ul>
32   * <li>{@link Empty}, which represents the empty {@code Stream}.</li>
33   * <li>{@link Cons}, which represents a {@code Stream} containing one or more elements.</li>
34   * </ul>
35   *
36   * Methods to obtain a {@code Stream}:
37   *
38   * <pre>
39   * <code>
40   * // factory methods
41   * Stream.empty()                  // = Stream.of() = Nil.instance()
42   * Stream.of(x)                    // = new Cons&lt;&gt;(x, Nil.instance())
43   * Stream.of(Object...)            // e.g. Stream.of(1, 2, 3)
44   * Stream.ofAll(Iterable)          // e.g. Stream.ofAll(List.of(1, 2, 3)) = 1, 2, 3
45   * Stream.ofAll(&lt;primitive array&gt;) // e.g. List.ofAll(1, 2, 3) = 1, 2, 3
46   *
47   * // int sequences
48   * Stream.from(0)                  // = 0, 1, 2, 3, ...
49   * Stream.range(0, 3)              // = 0, 1, 2
50   * Stream.rangeClosed(0, 3)        // = 0, 1, 2, 3
51   *
52   * // generators
53   * Stream.cons(Object, Supplier)   // e.g. Stream.cons(current, () -&gt; next(current));
54   * Stream.continually(Supplier)    // e.g. Stream.continually(Math::random);
55   * Stream.iterate(Object, Function)// e.g. Stream.iterate(1, i -&gt; i * 2);
56   * </code>
57   * </pre>
58   *
59   * Factory method applications:
60   *
61   * <pre>
62   * <code>
63   * Stream&lt;Integer&gt;       s1 = Stream.of(1);
64   * Stream&lt;Integer&gt;       s2 = Stream.of(1, 2, 3);
65   *                       // = Stream.of(new Integer[] {1, 2, 3});
66   *
67   * Stream&lt;int[]&gt;         s3 = Stream.ofAll(1, 2, 3);
68   * Stream&lt;List&lt;Integer&gt;&gt; s4 = Stream.ofAll(List.of(1, 2, 3));
69   *
70   * Stream&lt;Integer&gt;       s5 = Stream.ofAll(1, 2, 3);
71   * Stream&lt;Integer&gt;       s6 = Stream.ofAll(List.of(1, 2, 3));
72   *
73   * // cuckoo's egg
74   * Stream&lt;Integer[]&gt;     s7 = Stream.&lt;Integer[]&gt; of(new Integer[] {1, 2, 3});
75   * </code>
76   * </pre>
77   *
78   * Example: Generating prime numbers
79   *
80   * <pre>
81   * <code>
82   * // = Stream(2L, 3L, 5L, 7L, ...)
83   * Stream.iterate(2L, PrimeNumbers::nextPrimeFrom)
84   *
85   * // helpers
86   *
87   * static long nextPrimeFrom(long num) {
88   *     return Stream.from(num + 1).find(PrimeNumbers::isPrime).get();
89   * }
90   *
91   * static boolean isPrime(long num) {
92   *     return !Stream.rangeClosed(2L, (long) Math.sqrt(num)).exists(d -&gt; num % d == 0);
93   * }
94   * </code>
95   * </pre>
96   *
97   * See Okasaki, Chris: <em>Purely Functional Data Structures</em> (p. 34 ff.). Cambridge, 2003.
98   *
99   * @param <T> component type of this Stream
100  * @author Daniel Dietrich, Jörgen Andersson, Ruslan Sennov
101  */
102 public interface Stream<T> extends LinearSeq<T> {
103 
104     long serialVersionUID = 1L;
105 
106     /**
107      * Returns a {@link java.util.stream.Collector} which may be used in conjunction with
108      * {@link java.util.stream.Stream#collect(java.util.stream.Collector)} to obtain a {@link Stream}.
109      *
110      * @param <T> Component type of the Stream.
111      * @return A io.vavr.collection.Stream Collector.
112      */
113     static <T> Collector<T, ArrayList<T>, Stream<T>> collector() {
114         final Supplier<ArrayList<T>> supplier = ArrayList::new;
115         final BiConsumer<ArrayList<T>, T> accumulator = ArrayList::add;
116         final BinaryOperator<ArrayList<T>> combiner = (left, right) -> {
117             left.addAll(right);
118             return left;
119         };
120         final Function<ArrayList<T>, Stream<T>> finisher = Stream::ofAll;
121         return Collector.of(supplier, accumulator, combiner, finisher);
122     }
123 
124     /**
125      * Lazily creates a Stream in O(1) which traverses along the concatenation of the given iterables.
126      *
127      * @param iterables The iterables
128      * @param <T>       Component type.
129      * @return A new {@code Stream}
130      */
131     @SuppressWarnings("varargs")
132     @SafeVarargs
133     static <T> Stream<T> concat(Iterable<? extends T>... iterables) {
134         return Iterator.concat(iterables).toStream();
135     }
136 
137     /**
138      * Lazily creates a Stream in O(1) which traverses along the concatenation of the given iterables.
139      *
140      * @param iterables The iterable of iterables
141      * @param <T>       Component type.
142      * @return A new {@code Stream}
143      */
144     static <T> Stream<T> concat(Iterable<? extends Iterable<? extends T>> iterables) {
145         return Iterator.<T> concat(iterables).toStream();
146     }
147 
148     /**
149      * Returns an infinitely long Stream of {@code int} values starting from {@code from}.
150      * <p>
151      * The {@code Stream} extends to {@code Integer.MIN_VALUE} when passing {@code Integer.MAX_VALUE}.
152      *
153      * @param value a start int value
154      * @return a new Stream of int values starting from {@code from}
155      */
156     static Stream<Integer> from(int value) {
157         return Stream.ofAll(Iterator.from(value));
158     }
159 
160     /**
161      * Returns an infinite long Stream of {@code int} values starting from {@code value} and spaced by {@code step}.
162      * <p>
163      * The {@code Stream} extends to {@code Integer.MIN_VALUE} when passing {@code Integer.MAX_VALUE}.
164      *
165      * @param value a start int value
166      * @param step  the step by which to advance on each next value
167      * @return a new {@code Stream} of int values starting from {@code from}
168      */
169     static Stream<Integer> from(int value, int step) {
170         return Stream.ofAll(Iterator.from(value, step));
171     }
172 
173     /**
174      * Returns an infinitely long Stream of {@code long} values starting from {@code from}.
175      * <p>
176      * The {@code Stream} extends to {@code Integer.MIN_VALUE} when passing {@code Long.MAX_VALUE}.
177      *
178      * @param value a start long value
179      * @return a new Stream of long values starting from {@code from}
180      */
181     static Stream<Long> from(long value) {
182         return Stream.ofAll(Iterator.from(value));
183     }
184 
185     /**
186      * Returns an infinite long Stream of {@code long} values starting from {@code value} and spaced by {@code step}.
187      * <p>
188      * The {@code Stream} extends to {@code Long.MIN_VALUE} when passing {@code Long.MAX_VALUE}.
189      *
190      * @param value a start long value
191      * @param step  the step by which to advance on each next value
192      * @return a new {@code Stream} of long values starting from {@code from}
193      */
194     static Stream<Long> from(long value, long step) {
195         return Stream.ofAll(Iterator.from(value, step));
196     }
197 
198     /**
199      * Generates an (theoretically) infinitely long Stream using a value Supplier.
200      *
201      * @param supplier A Supplier of Stream values
202      * @param <T>      value type
203      * @return A new Stream
204      */
205     static <T> Stream<T> continually(Supplier<? extends T> supplier) {
206         Objects.requireNonNull(supplier, "supplier is null");
207         return Stream.ofAll(Iterator.continually(supplier));
208     }
209 
210     /**
211      * Generates a (theoretically) infinitely long Stream using a function to calculate the next value
212      * based on the previous.
213      *
214      * @param seed The first value in the Stream
215      * @param f    A function to calculate the next value based on the previous
216      * @param <T>  value type
217      * @return A new Stream
218      */
219     static <T> Stream<T> iterate(T seed, Function<? super T, ? extends T> f) {
220         Objects.requireNonNull(f, "f is null");
221         return Stream.ofAll(Iterator.iterate(seed, f));
222     }
223 
224     /**
225      * Constructs a Stream of a head element and a tail supplier.
226      *
227      * @param head         The head element of the Stream
228      * @param tailSupplier A supplier of the tail values. To end the stream, return {@link Stream#empty}.
229      * @param <T>          value type
230      * @return A new Stream
231      */
232     @SuppressWarnings("unchecked")
233     static <T> Stream<T> cons(T head, Supplier<? extends Stream<? extends T>> tailSupplier) {
234         Objects.requireNonNull(tailSupplier, "tailSupplier is null");
235         return new ConsImpl<>(head, (Supplier<Stream<T>>) tailSupplier);
236     }
237 
238     /**
239      * Returns the single instance of Nil. Convenience method for {@code Nil.instance()}.
240      * <p>
241      * Note: this method intentionally returns type {@code Stream} and not {@code Nil}. This comes handy when folding.
242      * If you explicitly need type {@code Nil} use {@linkplain Empty#instance()}.
243      *
244      * @param <T> Component type of Nil, determined by type inference in the particular context.
245      * @return The empty list.
246      */
247     static <T> Stream<T> empty() {
248         return Empty.instance();
249     }
250 
251     /**
252      * Narrows a widened {@code Stream<? extends T>} to {@code Stream<T>}
253      * by performing a type-safe cast. This is eligible because immutable/read-only
254      * collections are covariant.
255      *
256      * @param stream A {@code Stream}.
257      * @param <T>    Component type of the {@code Stream}.
258      * @return the given {@code stream} instance as narrowed type {@code Stream<T>}.
259      */
260     @SuppressWarnings("unchecked")
261     static <T> Stream<T> narrow(Stream<? extends T> stream) {
262         return (Stream<T>) stream;
263     }
264 
265     /**
266      * Returns a singleton {@code Stream}, i.e. a {@code Stream} of one element.
267      *
268      * @param element An element.
269      * @param <T>     The component type
270      * @return A new Stream instance containing the given element
271      */
272     static <T> Stream<T> of(T element) {
273         return cons(element, Empty::instance);
274     }
275 
276     /**
277      * Creates a Stream of the given elements.
278      *
279      * <pre><code>  Stream.of(1, 2, 3, 4)
280      * = Nil.instance().prepend(4).prepend(3).prepend(2).prepend(1)
281      * = new Cons(1, new Cons(2, new Cons(3, new Cons(4, Nil.instance()))))</code></pre>
282      *
283      * @param <T>      Component type of the Stream.
284      * @param elements Zero or more elements.
285      * @return A list containing the given elements in the same order.
286      */
287     @SafeVarargs
288     static <T> Stream<T> of(T... elements) {
289         Objects.requireNonNull(elements, "elements is null");
290         return Stream.ofAll(new Iterator<T>() {
291             int i = 0;
292 
293             @Override
294             public boolean hasNext() {
295                 return i < elements.length;
296             }
297 
298             @Override
299             public T next() {
300                 return elements[i++];
301             }
302         });
303     }
304 
305     /**
306      * Returns a Stream containing {@code n} values of a given Function {@code f}
307      * over a range of integer values from 0 to {@code n - 1}.
308      *
309      * @param <T> Component type of the Stream
310      * @param n   The number of elements in the Stream
311      * @param f   The Function computing element values
312      * @return A Stream consisting of elements {@code f(0),f(1), ..., f(n - 1)}
313      * @throws NullPointerException if {@code f} is null
314      */
315     static <T> Stream<T> tabulate(int n, Function<? super Integer, ? extends T> f) {
316         Objects.requireNonNull(f, "f is null");
317         return Stream.ofAll(io.vavr.collection.Collections.tabulate(n, f));
318     }
319 
320     /**
321      * Returns a Stream containing {@code n} values supplied by a given Supplier {@code s}.
322      *
323      * @param <T> Component type of the Stream
324      * @param n   The number of elements in the Stream
325      * @param s   The Supplier computing element values
326      * @return A Stream of size {@code n}, where each element contains the result supplied by {@code s}.
327      * @throws NullPointerException if {@code s} is null
328      */
329     static <T> Stream<T> fill(int n, Supplier<? extends T> s) {
330         Objects.requireNonNull(s, "s is null");
331         return Stream.ofAll(io.vavr.collection.Collections.fill(n, s));
332     }
333 
334     /**
335      * Creates a Stream of the given elements.
336      *
337      * @param <T>      Component type of the Stream.
338      * @param elements An Iterable of elements.
339      * @return A Stream containing the given elements in the same order.
340      */
341     @SuppressWarnings("unchecked")
342     static <T> Stream<T> ofAll(Iterable<? extends T> elements) {
343         Objects.requireNonNull(elements, "elements is null");
344         if (elements instanceof Stream) {
345             return (Stream<T>) elements;
346         } else {
347             return StreamFactory.create(elements.iterator());
348         }
349     }
350 
351     /**
352      * Creates a Stream that contains the elements of the given {@link java.util.stream.Stream}.
353      *
354      * @param javaStream A {@link java.util.stream.Stream}
355      * @param <T>        Component type of the Stream.
356      * @return A Stream containing the given elements in the same order.
357      */
358     static <T> Stream<T> ofAll(java.util.stream.Stream<? extends T> javaStream) {
359         Objects.requireNonNull(javaStream, "javaStream is null");
360         return StreamFactory.create(javaStream.iterator());
361     }
362 
363     /**
364      * Creates a Stream from boolean values.
365      *
366      * @param elements boolean values
367      * @return A new Stream of Boolean values
368      * @throws NullPointerException if elements is null
369      */
370     static Stream<Boolean> ofAll(boolean... elements) {
371         Objects.requireNonNull(elements, "elements is null");
372         return Stream.ofAll(Iterator.ofAll(elements));
373     }
374 
375     /**
376      * Creates a Stream from byte values.
377      *
378      * @param elements byte values
379      * @return A new Stream of Byte values
380      * @throws NullPointerException if elements is null
381      */
382     static Stream<Byte> ofAll(byte... elements) {
383         Objects.requireNonNull(elements, "elements is null");
384         return Stream.ofAll(Iterator.ofAll(elements));
385     }
386 
387     /**
388      * Creates a Stream from char values.
389      *
390      * @param elements char values
391      * @return A new Stream of Character values
392      * @throws NullPointerException if elements is null
393      */
394     static Stream<Character> ofAll(char... elements) {
395         Objects.requireNonNull(elements, "elements is null");
396         return Stream.ofAll(Iterator.ofAll(elements));
397     }
398 
399     /**
400      * Creates a Stream values double values.
401      *
402      * @param elements double values
403      * @return A new Stream of Double values
404      * @throws NullPointerException if elements is null
405      */
406     static Stream<Double> ofAll(double... elements) {
407         Objects.requireNonNull(elements, "elements is null");
408         return Stream.ofAll(Iterator.ofAll(elements));
409     }
410 
411     /**
412      * Creates a Stream from float values.
413      *
414      * @param elements float values
415      * @return A new Stream of Float values
416      * @throws NullPointerException if elements is null
417      */
418     static Stream<Float> ofAll(float... elements) {
419         Objects.requireNonNull(elements, "elements is null");
420         return Stream.ofAll(Iterator.ofAll(elements));
421     }
422 
423     /**
424      * Creates a Stream from int values.
425      *
426      * @param elements int values
427      * @return A new Stream of Integer values
428      * @throws NullPointerException if elements is null
429      */
430     static Stream<Integer> ofAll(int... elements) {
431         Objects.requireNonNull(elements, "elements is null");
432         return Stream.ofAll(Iterator.ofAll(elements));
433     }
434 
435     /**
436      * Creates a Stream from long values.
437      *
438      * @param elements long values
439      * @return A new Stream of Long values
440      * @throws NullPointerException if elements is null
441      */
442     static Stream<Long> ofAll(long... elements) {
443         Objects.requireNonNull(elements, "elements is null");
444         return Stream.ofAll(Iterator.ofAll(elements));
445     }
446 
447     /**
448      * Creates a Stream from short values.
449      *
450      * @param elements short values
451      * @return A new Stream of Short values
452      * @throws NullPointerException if elements is null
453      */
454     static Stream<Short> ofAll(short... elements) {
455         Objects.requireNonNull(elements, "elements is null");
456         return Stream.ofAll(Iterator.ofAll(elements));
457     }
458 
459     static Stream<Character> range(char from, char toExclusive) {
460         return Stream.ofAll(Iterator.range(from, toExclusive));
461     }
462 
463     static Stream<Character> rangeBy(char from, char toExclusive, int step) {
464         return Stream.ofAll(Iterator.rangeBy(from, toExclusive, step));
465     }
466 
467     @GwtIncompatible
468     static Stream<Double> rangeBy(double from, double toExclusive, double step) {
469         return Stream.ofAll(Iterator.rangeBy(from, toExclusive, step));
470     }
471 
472     /**
473      * Creates a Stream of int numbers starting from {@code from}, extending to {@code toExclusive - 1}.
474      * <p>
475      * Examples:
476      * <pre>
477      * <code>
478      * Stream.range(0, 0)  // = Stream()
479      * Stream.range(2, 0)  // = Stream()
480      * Stream.range(-2, 2) // = Stream(-2, -1, 0, 1)
481      * </code>
482      * </pre>
483      *
484      * @param from        the first number
485      * @param toExclusive the last number + 1
486      * @return a range of int values as specified or {@code Nil} if {@code from >= toExclusive}
487      */
488     static Stream<Integer> range(int from, int toExclusive) {
489         return Stream.ofAll(Iterator.range(from, toExclusive));
490     }
491 
492     /**
493      * Creates a Stream of int numbers starting from {@code from}, extending to {@code toExclusive - 1},
494      * with {@code step}.
495      * <p>
496      * Examples:
497      * <pre>
498      * <code>
499      * Stream.rangeBy(1, 3, 1)  // = Stream(1, 2)
500      * Stream.rangeBy(1, 4, 2)  // = Stream(1, 3)
501      * Stream.rangeBy(4, 1, -2) // = Stream(4, 2)
502      * Stream.rangeBy(4, 1, 2)  // = Stream()
503      * </code>
504      * </pre>
505      *
506      * @param from        the first number
507      * @param toExclusive the last number + 1
508      * @param step        the step
509      * @return a range of long values as specified or {@code Nil} if<br>
510      * {@code from >= toInclusive} and {@code step > 0} or<br>
511      * {@code from <= toInclusive} and {@code step < 0}
512      * @throws IllegalArgumentException if {@code step} is zero
513      */
514     static Stream<Integer> rangeBy(int from, int toExclusive, int step) {
515         return Stream.ofAll(Iterator.rangeBy(from, toExclusive, step));
516     }
517 
518     /**
519      * Creates a Stream of long numbers starting from {@code from}, extending to {@code toExclusive - 1}.
520      * <p>
521      * Examples:
522      * <pre>
523      * <code>
524      * Stream.range(0L, 0L)  // = Stream()
525      * Stream.range(2L, 0L)  // = Stream()
526      * Stream.range(-2L, 2L) // = Stream(-2L, -1L, 0L, 1L)
527      * </code>
528      * </pre>
529      *
530      * @param from        the first number
531      * @param toExclusive the last number + 1
532      * @return a range of long values as specified or {@code Nil} if {@code from >= toExclusive}
533      */
534     static Stream<Long> range(long from, long toExclusive) {
535         return Stream.ofAll(Iterator.range(from, toExclusive));
536     }
537 
538     /**
539      * Creates a Stream of long numbers starting from {@code from}, extending to {@code toExclusive - 1},
540      * with {@code step}.
541      * <p>
542      * Examples:
543      * <pre>
544      * <code>
545      * Stream.rangeBy(1L, 3L, 1L)  // = Stream(1L, 2L)
546      * Stream.rangeBy(1L, 4L, 2L)  // = Stream(1L, 3L)
547      * Stream.rangeBy(4L, 1L, -2L) // = Stream(4L, 2L)
548      * Stream.rangeBy(4L, 1L, 2L)  // = Stream()
549      * </code>
550      * </pre>
551      *
552      * @param from        the first number
553      * @param toExclusive the last number + 1
554      * @param step        the step
555      * @return a range of long values as specified or {@code Nil} if<br>
556      * {@code from >= toInclusive} and {@code step > 0} or<br>
557      * {@code from <= toInclusive} and {@code step < 0}
558      * @throws IllegalArgumentException if {@code step} is zero
559      */
560     static Stream<Long> rangeBy(long from, long toExclusive, long step) {
561         return Stream.ofAll(Iterator.rangeBy(from, toExclusive, step));
562     }
563 
564     static Stream<Character> rangeClosed(char from, char toInclusive) {
565         return Stream.ofAll(Iterator.rangeClosed(from, toInclusive));
566     }
567 
568     static Stream<Character> rangeClosedBy(char from, char toInclusive, int step) {
569         return Stream.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
570     }
571 
572     @GwtIncompatible
573     static Stream<Double> rangeClosedBy(double from, double toInclusive, double step) {
574         return Stream.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
575     }
576 
577     /**
578      * Creates a Stream of int numbers starting from {@code from}, extending to {@code toInclusive}.
579      * <p>
580      * Examples:
581      * <pre>
582      * <code>
583      * Stream.rangeClosed(0, 0)  // = Stream(0)
584      * Stream.rangeClosed(2, 0)  // = Stream()
585      * Stream.rangeClosed(-2, 2) // = Stream(-2, -1, 0, 1, 2)
586      * </code>
587      * </pre>
588      *
589      * @param from        the first number
590      * @param toInclusive the last number
591      * @return a range of int values as specified or {@code Nil} if {@code from > toInclusive}
592      */
593     static Stream<Integer> rangeClosed(int from, int toInclusive) {
594         return Stream.ofAll(Iterator.rangeClosed(from, toInclusive));
595     }
596 
597     /**
598      * Creates a Stream of int numbers starting from {@code from}, extending to {@code toInclusive},
599      * with {@code step}.
600      * <p>
601      * Examples:
602      * <pre>
603      * <code>
604      * Stream.rangeClosedBy(1, 3, 1)  // = Stream(1, 2, 3)
605      * Stream.rangeClosedBy(1, 4, 2)  // = Stream(1, 3)
606      * Stream.rangeClosedBy(4, 1, -2) // = Stream(4, 2)
607      * Stream.rangeClosedBy(4, 1, 2)  // = Stream()
608      * </code>
609      * </pre>
610      *
611      * @param from        the first number
612      * @param toInclusive the last number
613      * @param step        the step
614      * @return a range of int values as specified or {@code Nil} if<br>
615      * {@code from > toInclusive} and {@code step > 0} or<br>
616      * {@code from < toInclusive} and {@code step < 0}
617      * @throws IllegalArgumentException if {@code step} is zero
618      */
619     static Stream<Integer> rangeClosedBy(int from, int toInclusive, int step) {
620         return Stream.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
621     }
622 
623     /**
624      * Creates a Stream of long numbers starting from {@code from}, extending to {@code toInclusive}.
625      * <p>
626      * Examples:
627      * <pre>
628      * <code>
629      * Stream.rangeClosed(0L, 0L)  // = Stream(0L)
630      * Stream.rangeClosed(2L, 0L)  // = Stream()
631      * Stream.rangeClosed(-2L, 2L) // = Stream(-2L, -1L, 0L, 1L, 2L)
632      * </code>
633      * </pre>
634      *
635      * @param from        the first number
636      * @param toInclusive the last number
637      * @return a range of long values as specified or {@code Nil} if {@code from > toInclusive}
638      */
639     static Stream<Long> rangeClosed(long from, long toInclusive) {
640         return Stream.ofAll(Iterator.rangeClosed(from, toInclusive));
641     }
642 
643     /**
644      * Creates a Stream of long numbers starting from {@code from}, extending to {@code toInclusive},
645      * with {@code step}.
646      * <p>
647      * Examples:
648      * <pre>
649      * <code>
650      * Stream.rangeClosedBy(1L, 3L, 1L)  // = Stream(1L, 2L, 3L)
651      * Stream.rangeClosedBy(1L, 4L, 2L)  // = Stream(1L, 3L)
652      * Stream.rangeClosedBy(4L, 1L, -2L) // = Stream(4L, 2L)
653      * Stream.rangeClosedBy(4L, 1L, 2L)  // = Stream()
654      * </code>
655      * </pre>
656      *
657      * @param from        the first number
658      * @param toInclusive the last number
659      * @param step        the step
660      * @return a range of int values as specified or {@code Nil} if<br>
661      * {@code from > toInclusive} and {@code step > 0} or<br>
662      * {@code from < toInclusive} and {@code step < 0}
663      * @throws IllegalArgumentException if {@code step} is zero
664      */
665     static Stream<Long> rangeClosedBy(long from, long toInclusive, long step) {
666         return Stream.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
667     }
668 
669     /**
670      * Transposes the rows and columns of a {@link Stream} matrix.
671      *
672      * @param <T> matrix element type
673      * @param matrix to be transposed.
674      * @return a transposed {@link Stream} matrix.
675      * @throws IllegalArgumentException if the row lengths of {@code matrix} differ.
676      * <p>
677      * ex: {@code
678      * Stream.transpose(Stream(Stream(1,2,3), Stream(4,5,6))) → Stream(Stream(1,4), Stream(2,5), Stream(3,6))
679      * }
680      */
681     static <T> Stream<Stream<T>> transpose(Stream<Stream<T>> matrix) {
682         return io.vavr.collection.Collections.transpose(matrix, Stream::ofAll, Stream::of);
683     }
684 
685     /**
686      * Creates a Stream from a seed value and a function.
687      * The function takes the seed at first.
688      * The function should return {@code None} when it's
689      * done generating the Stream, otherwise {@code Some} {@code Tuple}
690      * of the element for the next call and the value to add to the
691      * resulting Stream.
692      * <p>
693      * Example:
694      * <pre>
695      * <code>
696      * Stream.unfoldRight(10, x -&gt; x == 0
697      *             ? Option.none()
698      *             : Option.of(new Tuple2&lt;&gt;(x, x-1)));
699      * // Stream(10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
700      * </code>
701      * </pre>
702      *
703      * @param <T>  type of seeds
704      * @param <U>  type of unfolded values
705      * @param seed the start value for the iteration
706      * @param f    the function to get the next step of the iteration
707      * @return a Stream with the values built up by the iteration
708      * @throws NullPointerException if {@code f} is null
709      */
710     static <T, U> Stream<U> unfoldRight(T seed, Function<? super T, Option<Tuple2<? extends U, ? extends T>>> f) {
711         return Iterator.unfoldRight(seed, f).toStream();
712     }
713 
714     /**
715      * Creates a Stream from a seed value and a function.
716      * The function takes the seed at first.
717      * The function should return {@code None} when it's
718      * done generating the Stream, otherwise {@code Some} {@code Tuple}
719      * of the value to add to the resulting Stream and
720      * the element for the next call.
721      * <p>
722      * Example:
723      * <pre>
724      * <code>
725      * Stream.unfoldLeft(10, x -&gt; x == 0
726      *             ? Option.none()
727      *             : Option.of(new Tuple2&lt;&gt;(x-1, x)));
728      * // Stream(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
729      * </code>
730      * </pre>
731      *
732      * @param <T>  type of seeds
733      * @param <U>  type of unfolded values
734      * @param seed the start value for the iteration
735      * @param f    the function to get the next step of the iteration
736      * @return a Stream with the values built up by the iteration
737      * @throws NullPointerException if {@code f} is null
738      */
739     static <T, U> Stream<U> unfoldLeft(T seed, Function<? super T, Option<Tuple2<? extends T, ? extends U>>> f) {
740         return Iterator.unfoldLeft(seed, f).toStream();
741     }
742 
743     /**
744      * Creates a Stream from a seed value and a function.
745      * The function takes the seed at first.
746      * The function should return {@code None} when it's
747      * done generating the Stream, otherwise {@code Some} {@code Tuple}
748      * of the value to add to the resulting Stream and
749      * the element for the next call.
750      * <p>
751      * Example:
752      * <pre>
753      * <code>
754      * Stream.unfold(10, x -&gt; x == 0
755      *             ? Option.none()
756      *             : Option.of(new Tuple2&lt;&gt;(x-1, x)));
757      * // Stream(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
758      * </code>
759      * </pre>
760      *
761      * @param <T>  type of seeds and unfolded values
762      * @param seed the start value for the iteration
763      * @param f    the function to get the next step of the iteration
764      * @return a Stream with the values built up by the iteration
765      * @throws NullPointerException if {@code f} is null
766      */
767     static <T> Stream<T> unfold(T seed, Function<? super T, Option<Tuple2<? extends T, ? extends T>>> f) {
768         return Iterator.unfold(seed, f).toStream();
769     }
770 
771     /**
772      * Repeats an element infinitely often.
773      *
774      * @param t   An element
775      * @param <T> Element type
776      * @return A new Stream containing infinite {@code t}'s.
777      */
778     static <T> Stream<T> continually(T t) {
779         return Stream.ofAll(Iterator.continually(t));
780     }
781 
782     @Override
783     default Stream<T> append(T element) {
784         return isEmpty() ? Stream.of(element) : new AppendElements<>(head(), io.vavr.collection.Queue.of(element), this::tail);
785     }
786 
787     @Override
788     default Stream<T> appendAll(Iterable<? extends T> elements) {
789         Objects.requireNonNull(elements, "elements is null");
790         if (Collections.isEmpty(elements)) {
791             return this;
792         } else if (isEmpty()) {
793             return Stream.ofAll(elements);
794         } else {
795             return Stream.ofAll(Iterator.concat(this, elements));
796         }
797     }
798 
799     /**
800      * Appends itself to the end of stream with {@code mapper} function.
801      * <p>
802      * <strong>Example:</strong>
803      * <p>
804      * Well known Scala code for Fibonacci infinite sequence
805      * <pre>
806      * <code>
807      * val fibs:Stream[Int] = 0 #:: 1 #:: (fibs zip fibs.tail).map{ t =&gt; t._1 + t._2 }
808      * </code>
809      * </pre>
810      * can be transformed to
811      * <pre>
812      * <code>
813      * Stream.of(0, 1).appendSelf(self -&gt; self.zip(self.tail()).map(t -&gt; t._1 + t._2));
814      * </code>
815      * </pre>
816      *
817      * @param mapper an mapper
818      * @return a new Stream
819      */
820     default Stream<T> appendSelf(Function<? super Stream<T>, ? extends Stream<T>> mapper) {
821         Objects.requireNonNull(mapper, "mapper is null");
822         return isEmpty() ? this : new AppendSelf<>((Cons<T>) this, mapper).stream();
823     }
824 
825     @Override
826     default java.util.List<T> asJava() {
827         return JavaConverters.asJava(this, IMMUTABLE);
828     }
829 
830     @Override
831     default Stream<T> asJava(Consumer<? super java.util.List<T>> action) {
832         return Collections.asJava(this, action, IMMUTABLE);
833     }
834 
835     @Override
836     default java.util.List<T> asJavaMutable() {
837         return JavaConverters.asJava(this, MUTABLE);
838     }
839 
840     @Override
841     default Stream<T> asJavaMutable(Consumer<? super java.util.List<T>> action) {
842         return Collections.asJava(this, action, MUTABLE);
843     }
844 
845     @Override
846     default <R> Stream<R> collect(PartialFunction<? super T, ? extends R> partialFunction) {
847         return ofAll(iterator().<R> collect(partialFunction));
848     }
849     
850     @Override
851     default Stream<Stream<T>> combinations() {
852         return Stream.rangeClosed(0, length()).map(this::combinations).flatMap(Function.identity());
853     }
854 
855     @Override
856     default Stream<Stream<T>> combinations(int k) {
857         return Combinations.apply(this, Math.max(k, 0));
858     }
859 
860     @Override
861     default Iterator<Stream<T>> crossProduct(int power) {
862         return io.vavr.collection.Collections.crossProduct(Stream.empty(), this, power);
863     }
864 
865     /**
866      * Repeat the elements of this Stream infinitely.
867      * <p>
868      * Example:
869      * <pre>
870      * <code>
871      * // = 1, 2, 3, 1, 2, 3, 1, 2, 3, ...
872      * Stream.of(1, 2, 3).cycle();
873      * </code>
874      * </pre>
875      *
876      * @return A new Stream containing this elements cycled.
877      */
878     default Stream<T> cycle() {
879         return isEmpty() ? this : appendSelf(Function.identity());
880     }
881 
882     /**
883      * Repeat the elements of this Stream {@code count} times.
884      * <p>
885      * Example:
886      * <pre>
887      * <code>
888      * // = empty
889      * Stream.of(1, 2, 3).cycle(0);
890      *
891      * // = 1, 2, 3
892      * Stream.of(1, 2, 3).cycle(1);
893      *
894      * // = 1, 2, 3, 1, 2, 3, 1, 2, 3
895      * Stream.of(1, 2, 3).cycle(3);
896      * </code>
897      * </pre>
898      *
899      * @param count the number of cycles to be performed
900      * @return A new Stream containing this elements cycled {@code count} times.
901      */
902     default Stream<T> cycle(int count) {
903         if (count <= 0 || isEmpty()) {
904             return empty();
905         } else {
906             final Stream<T> self = this;
907             return Stream.ofAll(new Iterator<T>() {
908                 Stream<T> stream = self;
909                 int i = count - 1;
910 
911                 @Override
912                 public boolean hasNext() {
913                     return !stream.isEmpty() || i > 0;
914                 }
915 
916                 @Override
917                 public T next() {
918                     if (stream.isEmpty()) {
919                         i--;
920                         stream = self;
921                     }
922                     final T result = stream.head();
923                     stream = stream.tail();
924                     return result;
925                 }
926             });
927         }
928     }
929 
930     @Override
931     default Stream<T> distinct() {
932         return distinctBy(Function.identity());
933     }
934 
935     @Override
936     default Stream<T> distinctBy(Comparator<? super T> comparator) {
937         Objects.requireNonNull(comparator, "comparator is null");
938         final java.util.Set<T> seen = new java.util.TreeSet<>(comparator);
939         return filter(seen::add);
940     }
941 
942     @Override
943     default <U> Stream<T> distinctBy(Function<? super T, ? extends U> keyExtractor) {
944         final java.util.Set<U> seen = new java.util.HashSet<>();
945         return filter(t -> seen.add(keyExtractor.apply(t)));
946     }
947 
948     @Override
949     default Stream<T> drop(int n) {
950         Stream<T> stream = this;
951         while (n-- > 0 && !stream.isEmpty()) {
952             stream = stream.tail();
953         }
954         return stream;
955     }
956 
957     @Override
958     default Stream<T> dropUntil(Predicate<? super T> predicate) {
959         return io.vavr.collection.Collections.dropUntil(this, predicate);
960     }
961 
962     @Override
963     default Stream<T> dropWhile(Predicate<? super T> predicate) {
964         Objects.requireNonNull(predicate, "predicate is null");
965         return dropUntil(predicate.negate());
966     }
967 
968     @Override
969     default Stream<T> dropRight(int n) {
970         if (n <= 0) {
971             return this;
972         } else {
973             return DropRight.apply(take(n).toList(), io.vavr.collection.List.empty(), drop(n));
974         }
975     }
976 
977     @Override
978     default Stream<T> dropRightUntil(Predicate<? super T> predicate) {
979         return io.vavr.collection.Collections.dropUntil(reverse(), predicate).reverse();
980     }
981 
982     @Override
983     default Stream<T> dropRightWhile(Predicate<? super T> predicate) {
984         Objects.requireNonNull(predicate, "predicate is null");
985         return dropRightUntil(predicate.negate());
986     }
987 
988     @Override
989     default Stream<T> filter(Predicate<? super T> predicate) {
990         Objects.requireNonNull(predicate, "predicate is null");
991         if (isEmpty()) {
992             return this;
993         } else {
994             Stream<T> stream = this;
995             while (!stream.isEmpty() && !predicate.test(stream.head())) {
996                 stream = stream.tail();
997             }
998             final Stream<T> finalStream = stream;
999             return stream.isEmpty() ? Stream.empty()
1000                                     : cons(stream.head(), () -> finalStream.tail().filter(predicate));
1001         }
1002     }
1003 
1004     @Override
1005     default <U> Stream<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper) {
1006         Objects.requireNonNull(mapper, "mapper is null");
1007         return isEmpty() ? Empty.instance() : Stream.ofAll(new Iterator<U>() {
1008 
1009             final Iterator<? extends T> inputs = Stream.this.iterator();
1010             java.util.Iterator<? extends U> current = java.util.Collections.emptyIterator();
1011 
1012             @Override
1013             public boolean hasNext() {
1014                 boolean currentHasNext;
1015                 while (!(currentHasNext = current.hasNext()) && inputs.hasNext()) {
1016                     current = mapper.apply(inputs.next()).iterator();
1017                 }
1018                 return currentHasNext;
1019             }
1020 
1021             @Override
1022             public U next() {
1023                 return current.next();
1024             }
1025         });
1026     }
1027 
1028     @Override
1029     default T get(int index) {
1030         if (isEmpty()) {
1031             throw new IndexOutOfBoundsException("get(" + index + ") on Nil");
1032         }
1033         if (index < 0) {
1034             throw new IndexOutOfBoundsException("get(" + index + ")");
1035         }
1036         Stream<T> stream = this;
1037         for (int i = index - 1; i >= 0; i--) {
1038             stream = stream.tail();
1039             if (stream.isEmpty()) {
1040                 throw new IndexOutOfBoundsException("get(" + index + ") on Stream of size " + (index - i));
1041             }
1042         }
1043         return stream.head();
1044     }
1045 
1046     @Override
1047     default <C> Map<C, Stream<T>> groupBy(Function<? super T, ? extends C> classifier) {
1048         return io.vavr.collection.Collections.groupBy(this, classifier, Stream::ofAll);
1049     }
1050 
1051     @Override
1052     default Iterator<Stream<T>> grouped(int size) {
1053         return sliding(size, size);
1054     }
1055 
1056     @Override
1057     default boolean hasDefiniteSize() {
1058         return false;
1059     }
1060 
1061     @Override
1062     default int indexOf(T element, int from) {
1063         int index = 0;
1064         for (Stream<T> stream = this; !stream.isEmpty(); stream = stream.tail(), index++) {
1065             if (index >= from && Objects.equals(stream.head(), element)) {
1066                 return index;
1067             }
1068         }
1069         return -1;
1070     }
1071 
1072     @Override
1073     default Stream<T> init() {
1074         if (isEmpty()) {
1075             throw new UnsupportedOperationException("init of empty stream");
1076         } else {
1077             final Stream<T> tail = tail();
1078             if (tail.isEmpty()) {
1079                 return Empty.instance();
1080             } else {
1081                 return cons(head(), tail::init);
1082             }
1083         }
1084     }
1085 
1086     @Override
1087     default Option<Stream<T>> initOption() {
1088         return isEmpty() ? Option.none() : Option.some(init());
1089     }
1090 
1091     @Override
1092     default Stream<T> insert(int index, T element) {
1093         if (index < 0) {
1094             throw new IndexOutOfBoundsException("insert(" + index + ", e)");
1095         } else if (index == 0) {
1096             return cons(element, () -> this);
1097         } else if (isEmpty()) {
1098             throw new IndexOutOfBoundsException("insert(" + index + ", e) on Nil");
1099         } else {
1100             return cons(head(), () -> tail().insert(index - 1, element));
1101         }
1102     }
1103 
1104     @Override
1105     default Stream<T> insertAll(int index, Iterable<? extends T> elements) {
1106         Objects.requireNonNull(elements, "elements is null");
1107         if (index < 0) {
1108             throw new IndexOutOfBoundsException("insertAll(" + index + ", elements)");
1109         } else if (index == 0) {
1110             return isEmpty() ? Stream.ofAll(elements) : Stream.<T> ofAll(elements).appendAll(this);
1111         } else if (isEmpty()) {
1112             throw new IndexOutOfBoundsException("insertAll(" + index + ", elements) on Nil");
1113         } else {
1114             return cons(head(), () -> tail().insertAll(index - 1, elements));
1115         }
1116     }
1117 
1118     @Override
1119     default Stream<T> intersperse(T element) {
1120         if (isEmpty()) {
1121             return this;
1122         } else {
1123             return cons(head(), () -> {
1124                 final Stream<T> tail = tail();
1125                 return tail.isEmpty() ? tail : cons(element, () -> tail.intersperse(element));
1126             });
1127         }
1128     }
1129 
1130     /**
1131      * A {@code Stream} is computed synchronously.
1132      *
1133      * @return false
1134      */
1135     @Override
1136     default boolean isAsync() {
1137         return false;
1138     }
1139 
1140     /**
1141      * A {@code Stream} is computed lazily.
1142      *
1143      * @return true
1144      */
1145     @Override
1146     default boolean isLazy() {
1147         return true;
1148     }
1149 
1150     @Override
1151     default boolean isTraversableAgain() {
1152         return true;
1153     }
1154 
1155     @Override
1156     default int lastIndexOf(T element, int end) {
1157         int result = -1, index = 0;
1158         for (Stream<T> stream = this; index <= end && !stream.isEmpty(); stream = stream.tail(), index++) {
1159             if (Objects.equals(stream.head(), element)) {
1160                 result = index;
1161             }
1162         }
1163         return result;
1164     }
1165 
1166     @Override
1167     default int length() {
1168         return foldLeft(0, (n, ignored) -> n + 1);
1169     }
1170 
1171     @Override
1172     default <U> Stream<U> map(Function<? super T, ? extends U> mapper) {
1173         Objects.requireNonNull(mapper, "mapper is null");
1174         if (isEmpty()) {
1175             return Empty.instance();
1176         } else {
1177             return cons(mapper.apply(head()), () -> tail().map(mapper));
1178         }
1179     }
1180 
1181     @Override
1182     default Stream<T> padTo(int length, T element) {
1183         if (length <= 0) {
1184             return this;
1185         } else if (isEmpty()) {
1186             return Stream.continually(element).take(length);
1187         } else {
1188             return cons(head(), () -> tail().padTo(length - 1, element));
1189         }
1190     }
1191 
1192     @Override
1193     default Stream<T> leftPadTo(int length, T element) {
1194         final int actualLength = length();
1195         if (length <= actualLength) {
1196             return this;
1197         } else {
1198             return Stream.continually(element).take(length - actualLength).appendAll(this);
1199         }
1200     }
1201 
1202     @Override
1203     default Stream<T> orElse(Iterable<? extends T> other) {
1204         return isEmpty() ? ofAll(other) : this;
1205     }
1206 
1207     @Override
1208     default Stream<T> orElse(Supplier<? extends Iterable<? extends T>> supplier) {
1209         return isEmpty() ? ofAll(supplier.get()) : this;
1210     }
1211 
1212     @Override
1213     default Stream<T> patch(int from, Iterable<? extends T> that, int replaced) {
1214         from = from < 0 ? 0 : from;
1215         replaced = replaced < 0 ? 0 : replaced;
1216         Stream<T> result = take(from).appendAll(that);
1217         from += replaced;
1218         result = result.appendAll(drop(from));
1219         return result;
1220     }
1221 
1222     @Override
1223     default Tuple2<Stream<T>, Stream<T>> partition(Predicate<? super T> predicate) {
1224         Objects.requireNonNull(predicate, "predicate is null");
1225         return Tuple.of(filter(predicate), filter(predicate.negate()));
1226     }
1227 
1228     @Override
1229     default Stream<T> peek(Consumer<? super T> action) {
1230         Objects.requireNonNull(action, "action is null");
1231         if (isEmpty()) {
1232             return this;
1233         } else {
1234             final T head = head();
1235             action.accept(head);
1236             return cons(head, () -> tail().peek(action));
1237         }
1238     }
1239 
1240     @Override
1241     default Stream<Stream<T>> permutations() {
1242         if (isEmpty()) {
1243             return Empty.instance();
1244         } else {
1245             final Stream<T> tail = tail();
1246             if (tail.isEmpty()) {
1247                 return Stream.of(this);
1248             } else {
1249                 final Stream<Stream<T>> zero = Empty.instance();
1250                 return distinct().foldLeft(zero, (xs, x) -> {
1251                     final Function<Stream<T>, Stream<T>> prepend = l -> l.prepend(x);
1252                     return xs.appendAll(remove(x).permutations().map(prepend));
1253                 });
1254             }
1255         }
1256     }
1257 
1258     @Override
1259     default Stream<T> prepend(T element) {
1260         return cons(element, () -> this);
1261     }
1262 
1263     @Override
1264     default Stream<T> prependAll(Iterable<? extends T> elements) {
1265         Objects.requireNonNull(elements, "elements is null");
1266         if (isEmpty()) {
1267             if (elements instanceof Stream) {
1268                 @SuppressWarnings("unchecked")
1269                 final Stream<T> stream = (Stream<T>) elements;
1270                 return stream;
1271             } else {
1272                 return Stream.ofAll(elements);
1273             }
1274         } else {
1275             return Stream.<T> ofAll(elements).appendAll(this);
1276         }
1277     }
1278 
1279     @Override
1280     default Stream<T> remove(T element) {
1281         if (isEmpty()) {
1282             return this;
1283         } else {
1284             final T head = head();
1285             return Objects.equals(head, element) ? tail() : cons(head, () -> tail().remove(element));
1286         }
1287     }
1288 
1289     @Override
1290     default Stream<T> removeFirst(Predicate<T> predicate) {
1291         Objects.requireNonNull(predicate, "predicate is null");
1292         if (isEmpty()) {
1293             return this;
1294         } else {
1295             final T head = head();
1296             return predicate.test(head) ? tail() : cons(head, () -> tail().removeFirst(predicate));
1297         }
1298     }
1299 
1300     @Override
1301     default Stream<T> removeLast(Predicate<T> predicate) {
1302         return isEmpty() ? this : reverse().removeFirst(predicate).reverse();
1303     }
1304 
1305     @Override
1306     default Stream<T> removeAt(int index) {
1307         if (index < 0) {
1308             throw new IndexOutOfBoundsException("removeAt(" + index + ")");
1309         } else if (index == 0) {
1310             return tail();
1311         } else if (isEmpty()) {
1312             throw new IndexOutOfBoundsException("removeAt() on Nil");
1313         } else {
1314             return cons(head(), () -> tail().removeAt(index - 1));
1315         }
1316     }
1317 
1318     @Override
1319     default Stream<T> removeAll(T element) {
1320         return io.vavr.collection.Collections.removeAll(this, element);
1321     }
1322 
1323     @Override
1324     default Stream<T> removeAll(Iterable<? extends T> elements) {
1325         return io.vavr.collection.Collections.removeAll(this, elements);
1326     }
1327 
1328     @Override
1329     default Stream<T> removeAll(Predicate<? super T> predicate) {
1330         return io.vavr.collection.Collections.removeAll(this, predicate);
1331     }
1332 
1333     @Override
1334     default Stream<T> replace(T currentElement, T newElement) {
1335         if (isEmpty()) {
1336             return this;
1337         } else {
1338             final T head = head();
1339             if (Objects.equals(head, currentElement)) {
1340                 return cons(newElement, this::tail);
1341             } else {
1342                 return cons(head, () -> tail().replace(currentElement, newElement));
1343             }
1344         }
1345     }
1346 
1347     @Override
1348     default Stream<T> replaceAll(T currentElement, T newElement) {
1349         if (isEmpty()) {
1350             return this;
1351         } else {
1352             final T head = head();
1353             final T newHead = Objects.equals(head, currentElement) ? newElement : head;
1354             return cons(newHead, () -> tail().replaceAll(currentElement, newElement));
1355         }
1356     }
1357 
1358     @Override
1359     default Stream<T> retainAll(Iterable<? extends T> elements) {
1360         return io.vavr.collection.Collections.retainAll(this, elements);
1361     }
1362 
1363     @Override
1364     default Stream<T> reverse() {
1365         return isEmpty() ? this : foldLeft(Stream.empty(), Stream::prepend);
1366     }
1367 
1368     @Override
1369     default Stream<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> operation) {
1370         return scanLeft(zero, operation);
1371     }
1372 
1373     @Override
1374     default <U> Stream<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
1375         // lazily streams the elements of an iterator
1376         return io.vavr.collection.Collections.scanLeft(this, zero, operation, Iterator::toStream);
1377     }
1378 
1379     // not lazy!
1380     @Override
1381     default <U> Stream<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
1382         return io.vavr.collection.Collections.scanRight(this, zero, operation, Iterator::toStream);
1383     }
1384 
1385     @Override
1386     default Stream<T> shuffle() {
1387         return io.vavr.collection.Collections.shuffle(this, Stream::ofAll);
1388     }
1389 
1390     @Override
1391     default Stream<T> slice(int beginIndex, int endIndex) {
1392         if (beginIndex >= endIndex || isEmpty()) {
1393             return empty();
1394         } else {
1395             final int lowerBound = Math.max(beginIndex, 0);
1396             if (lowerBound == 0) {
1397                 return cons(head(), () -> tail().slice(0, endIndex - 1));
1398             } else {
1399                 return tail().slice(lowerBound - 1, endIndex - 1);
1400             }
1401         }
1402     }
1403 
1404     @Override
1405     default Iterator<Stream<T>> slideBy(Function<? super T, ?> classifier) {
1406         return iterator().slideBy(classifier).map(Stream::ofAll);
1407     }
1408 
1409     @Override
1410     default Iterator<Stream<T>> sliding(int size) {
1411         return sliding(size, 1);
1412     }
1413 
1414     @Override
1415     default Iterator<Stream<T>> sliding(int size, int step) {
1416         return iterator().sliding(size, step).map(Stream::ofAll);
1417     }
1418 
1419     @Override
1420     default Stream<T> sorted() {
1421         return isEmpty() ? this : toJavaStream().sorted().collect(Stream.collector());
1422     }
1423 
1424     @Override
1425     default Stream<T> sorted(Comparator<? super T> comparator) {
1426         Objects.requireNonNull(comparator, "comparator is null");
1427         return isEmpty() ? this : toJavaStream().sorted(comparator).collect(Stream.collector());
1428     }
1429 
1430     @Override
1431     default <U extends Comparable<? super U>> Stream<T> sortBy(Function<? super T, ? extends U> mapper) {
1432         return sortBy(U::compareTo, mapper);
1433     }
1434 
1435     @Override
1436     default <U> Stream<T> sortBy(Comparator<? super U> comparator, Function<? super T, ? extends U> mapper) {
1437         final Function<? super T, ? extends U> domain = Function1.of(mapper::apply).memoized();
1438         return toJavaStream()
1439                 .sorted((e1, e2) -> comparator.compare(domain.apply(e1), domain.apply(e2)))
1440                 .collect(collector());
1441     }
1442 
1443     @Override
1444     default Tuple2<Stream<T>, Stream<T>> span(Predicate<? super T> predicate) {
1445         Objects.requireNonNull(predicate, "predicate is null");
1446         return Tuple.of(takeWhile(predicate), dropWhile(predicate));
1447     }
1448 
1449     @Override
1450     default Tuple2<Stream<T>, Stream<T>> splitAt(int n) {
1451         return Tuple.of(take(n), drop(n));
1452     }
1453 
1454     @Override
1455     default Tuple2<Stream<T>, Stream<T>> splitAt(Predicate<? super T> predicate) {
1456         Objects.requireNonNull(predicate, "predicate is null");
1457         return Tuple.of(takeWhile(predicate.negate()), dropWhile(predicate.negate()));
1458     }
1459 
1460     @Override
1461     default Tuple2<Stream<T>, Stream<T>> splitAtInclusive(Predicate<? super T> predicate) {
1462         final Tuple2<Stream<T>, Stream<T>> split = splitAt(predicate);
1463         if (split._2.isEmpty()) {
1464             return split;
1465         } else {
1466             return Tuple.of(split._1.append(split._2.head()), split._2.tail());
1467         }
1468     }
1469 
1470     @Override
1471     default String stringPrefix() {
1472         return "Stream";
1473     }
1474 
1475     @Override
1476     default Stream<T> subSequence(int beginIndex) {
1477         if (beginIndex < 0) {
1478             throw new IndexOutOfBoundsException("subSequence(" + beginIndex + ")");
1479         }
1480         Stream<T> result = this;
1481         for (int i = 0; i < beginIndex; i++, result = result.tail()) {
1482             if (result.isEmpty()) {
1483                 throw new IndexOutOfBoundsException("subSequence(" + beginIndex + ") on Stream of size " + i);
1484             }
1485         }
1486         return result;
1487     }
1488 
1489     @Override
1490     default Stream<T> subSequence(int beginIndex, int endIndex) {
1491         if (beginIndex < 0) {
1492             throw new IndexOutOfBoundsException("subSequence(" + beginIndex + ", " + endIndex + ")");
1493         }
1494         if (beginIndex > endIndex) {
1495             throw new IllegalArgumentException("subSequence(" + beginIndex + ", " + endIndex + ")");
1496         }
1497         if (beginIndex == endIndex) {
1498             return Empty.instance();
1499         } else if (isEmpty()) {
1500             throw new IndexOutOfBoundsException("subSequence of Nil");
1501         } else if (beginIndex == 0) {
1502             return cons(head(), () -> tail().subSequence(0, endIndex - 1));
1503         } else {
1504             return tail().subSequence(beginIndex - 1, endIndex - 1);
1505         }
1506     }
1507 
1508     @Override
1509     Stream<T> tail();
1510 
1511     @Override
1512     default Option<Stream<T>> tailOption() {
1513         return isEmpty() ? Option.none() : Option.some(tail());
1514     }
1515 
1516     @Override
1517     default Stream<T> take(int n) {
1518         if (n < 1 || isEmpty()) {
1519             return empty();
1520         } else if (n == 1) {
1521             return cons(head(), Stream::empty);
1522         } else {
1523             return cons(head(), () -> tail().take(n - 1));
1524         }
1525     }
1526 
1527     @Override
1528     default Stream<T> takeRight(int n) {
1529         Stream<T> right = this;
1530         Stream<T> remaining = drop(n);
1531         while (!remaining.isEmpty()) {
1532             right = right.tail();
1533             remaining = remaining.tail();
1534         }
1535         return right;
1536     }
1537 
1538     @Override
1539     default Stream<T> takeUntil(Predicate<? super T> predicate) {
1540         Objects.requireNonNull(predicate, "predicate is null");
1541         return takeWhile(predicate.negate());
1542     }
1543 
1544     @Override
1545     default Stream<T> takeWhile(Predicate<? super T> predicate) {
1546         Objects.requireNonNull(predicate, "predicate is null");
1547         if (isEmpty()) {
1548             return Empty.instance();
1549         } else {
1550             final T head = head();
1551             if (predicate.test(head)) {
1552                 return cons(head, () -> tail().takeWhile(predicate));
1553             } else {
1554                 return Empty.instance();
1555             }
1556         }
1557     }
1558 
1559     /**
1560      * Transforms this {@code Stream}.
1561      *
1562      * @param f   A transformation
1563      * @param <U> Type of transformation result
1564      * @return An instance of type {@code U}
1565      * @throws NullPointerException if {@code f} is null
1566      */
1567     default <U> U transform(Function<? super Stream<T>, ? extends U> f) {
1568         Objects.requireNonNull(f, "f is null");
1569         return f.apply(this);
1570     }
1571 
1572     @Override
1573     default <T1, T2> Tuple2<Stream<T1>, Stream<T2>> unzip(
1574             Function<? super T, Tuple2<? extends T1, ? extends T2>> unzipper) {
1575         Objects.requireNonNull(unzipper, "unzipper is null");
1576         final Stream<Tuple2<? extends T1, ? extends T2>> stream = map(unzipper);
1577         final Stream<T1> stream1 = stream.map(t -> t._1);
1578         final Stream<T2> stream2 = stream.map(t -> t._2);
1579         return Tuple.of(stream1, stream2);
1580     }
1581 
1582     @Override
1583     default <T1, T2, T3> Tuple3<Stream<T1>, Stream<T2>, Stream<T3>> unzip3(
1584             Function<? super T, Tuple3<? extends T1, ? extends T2, ? extends T3>> unzipper) {
1585         Objects.requireNonNull(unzipper, "unzipper is null");
1586         final Stream<Tuple3<? extends T1, ? extends T2, ? extends T3>> stream = map(unzipper);
1587         final Stream<T1> stream1 = stream.map(t -> t._1);
1588         final Stream<T2> stream2 = stream.map(t -> t._2);
1589         final Stream<T3> stream3 = stream.map(t -> t._3);
1590         return Tuple.of(stream1, stream2, stream3);
1591     }
1592 
1593     @Override
1594     default Stream<T> update(int index, T element) {
1595         if (isEmpty()) {
1596             throw new IndexOutOfBoundsException("update(" + index + ", e) on Nil");
1597         }
1598         if (index < 0) {
1599             throw new IndexOutOfBoundsException("update(" + index + ", e)");
1600         }
1601         Stream<T> preceding = Empty.instance();
1602         Stream<T> tail = this;
1603         for (int i = index; i > 0; i--, tail = tail.tail()) {
1604             if (tail.isEmpty()) {
1605                 throw new IndexOutOfBoundsException("update at " + index);
1606             }
1607             preceding = preceding.prepend(tail.head());
1608         }
1609         if (tail.isEmpty()) {
1610             throw new IndexOutOfBoundsException("update at " + index);
1611         }
1612         // skip the current head element because it is replaced
1613         return preceding.reverse().appendAll(tail.tail().prepend(element));
1614     }
1615 
1616     @Override
1617     default Stream<T> update(int index, Function<? super T, ? extends T> updater) {
1618         Objects.requireNonNull(updater, "updater is null");
1619         return update(index, updater.apply(get(index)));
1620     }
1621 
1622     @Override
1623     default <U> Stream<Tuple2<T, U>> zip(Iterable<? extends U> that) {
1624         return zipWith(that, Tuple::of);
1625     }
1626 
1627     @Override
1628     default <U, R> Stream<R> zipWith(Iterable<? extends U> that, BiFunction<? super T, ? super U, ? extends R> mapper) {
1629         Objects.requireNonNull(that, "that is null");
1630         Objects.requireNonNull(mapper, "mapper is null");
1631         return Stream.ofAll(iterator().zipWith(that, mapper));
1632     }
1633 
1634     @Override
1635     default <U> Stream<Tuple2<T, U>> zipAll(Iterable<? extends U> iterable, T thisElem, U thatElem) {
1636         Objects.requireNonNull(iterable, "iterable is null");
1637         return Stream.ofAll(iterator().zipAll(iterable, thisElem, thatElem));
1638     }
1639 
1640     @Override
1641     default Stream<Tuple2<T, Integer>> zipWithIndex() {
1642         return zipWithIndex(Tuple::of);
1643     }
1644 
1645     @Override
1646     default <U> Stream<U> zipWithIndex(BiFunction<? super T, ? super Integer, ? extends U> mapper) {
1647         Objects.requireNonNull(mapper, "mapper is null");
1648         return Stream.ofAll(iterator().zipWithIndex(mapper));
1649     }
1650 
1651     /**
1652      * Extends (continues) this {@code Stream} with a constantly repeated value.
1653      *
1654      * @param next value with which the stream should be extended
1655      * @return new {@code Stream} composed from this stream extended with a Stream of provided value
1656      */
1657     default Stream<T> extend(T next) {
1658         return Stream.ofAll(this.appendAll(Stream.continually(next)));
1659     }
1660 
1661     /**
1662      * Extends (continues) this {@code Stream} with values provided by a {@code Supplier}
1663      *
1664      * @param nextSupplier a supplier which will provide values for extending a stream
1665      * @return new {@code Stream} composed from this stream extended with values provided by the supplier
1666      */
1667     default Stream<T> extend(Supplier<? extends T> nextSupplier) {
1668         Objects.requireNonNull(nextSupplier, "nextSupplier is null");
1669         return Stream.ofAll(appendAll(Stream.continually(nextSupplier)));
1670     }
1671 
1672     /**
1673      * Extends (continues) this {@code Stream} with a Stream of values created by applying
1674      * consecutively provided {@code Function} to the last element of the original Stream.
1675      *
1676      * @param nextFunction a function which calculates the next value basing on the previous value
1677      * @return new {@code Stream} composed from this stream extended with values calculated by the provided function
1678      */
1679     default Stream<T> extend(Function<? super T, ? extends T> nextFunction) {
1680         Objects.requireNonNull(nextFunction, "nextFunction is null");
1681         if (isEmpty()) {
1682             return this;
1683         } else {
1684             final Stream<T> that = this;
1685             return Stream.ofAll(new AbstractIterator<T>() {
1686 
1687                 Stream<T> stream = that;
1688                 T last = null;
1689 
1690                 @Override
1691                 protected T getNext() {
1692                     if (stream.isEmpty()) {
1693                         stream = Stream.iterate(nextFunction.apply(last), nextFunction);
1694                     }
1695                     last = stream.head();
1696                     stream = stream.tail();
1697                     return last;
1698                 }
1699 
1700                 @Override
1701                 public boolean hasNext() {
1702                     return true;
1703                 }
1704             });
1705         }
1706     }
1707 
1708     /**
1709      * The empty Stream.
1710      * <p>
1711      * This is a singleton, i.e. not Cloneable.
1712      *
1713      * @param <T> Component type of the Stream.
1714      */
1715     final class Empty<T> implements Stream<T>, Serializable {
1716 
1717         private static final long serialVersionUID = 1L;
1718 
1719         private static final Empty<?> INSTANCE = new Empty<>();
1720 
1721         // hidden
1722         private Empty() {
1723         }
1724 
1725         /**
1726          * Returns the singleton empty Stream instance.
1727          *
1728          * @param <T> Component type of the Stream
1729          * @return The empty Stream
1730          */
1731         @SuppressWarnings("unchecked")
1732         public static <T> Empty<T> instance() {
1733             return (Empty<T>) INSTANCE;
1734         }
1735 
1736         @Override
1737         public T head() {
1738             throw new NoSuchElementException("head of empty stream");
1739         }
1740 
1741         @Override
1742         public boolean isEmpty() {
1743             return true;
1744         }
1745 
1746         @Override
1747         public Iterator<T> iterator() {
1748             return Iterator.empty();
1749         }
1750 
1751         @Override
1752         public Stream<T> tail() {
1753             throw new UnsupportedOperationException("tail of empty stream");
1754         }
1755 
1756         @Override
1757         public boolean equals(Object o) {
1758             return io.vavr.collection.Collections.equals(this, o);
1759         }
1760 
1761         @Override
1762         public int hashCode() {
1763             return io.vavr.collection.Collections.hashOrdered(this);
1764         }
1765 
1766         @Override
1767         public String toString() {
1768             return stringPrefix() + "()";
1769         }
1770 
1771         /**
1772          * Instance control for object serialization.
1773          *
1774          * @return The singleton instance of Nil.
1775          * @see java.io.Serializable
1776          */
1777         private Object readResolve() {
1778             return INSTANCE;
1779         }
1780     }
1781 
1782     /**
1783      * Non-empty {@code Stream}, consisting of a {@code head}, and {@code tail}.
1784      *
1785      * @param <T> Component type of the Stream.
1786      */
1787     abstract class Cons<T> implements Stream<T> {
1788 
1789         private static final long serialVersionUID = 1L;
1790 
1791         final T head;
1792         final Lazy<Stream<T>> tail;
1793 
1794         Cons(T head, Supplier<Stream<T>> tail) {
1795             Objects.requireNonNull(tail, "tail is null");
1796             this.head = head;
1797             this.tail = Lazy.of(tail);
1798         }
1799 
1800         @Override
1801         public T head() {
1802             return head;
1803         }
1804 
1805         @Override
1806         public boolean isEmpty() {
1807             return false;
1808         }
1809 
1810         @Override
1811         public Iterator<T> iterator() {
1812             return new StreamIterator<>(this);
1813         }
1814 
1815         @Override
1816         public boolean equals(Object o) {
1817             return io.vavr.collection.Collections.equals(this, o);
1818         }
1819 
1820         @Override
1821         public int hashCode() {
1822             return io.vavr.collection.Collections.hashOrdered(this);
1823         }
1824 
1825         @Override
1826         public String toString() {
1827             final StringBuilder builder = new StringBuilder(stringPrefix()).append("(");
1828             Stream<T> stream = this;
1829             while (stream != null && !stream.isEmpty()) {
1830                 final Cons<T> cons = (Cons<T>) stream;
1831                 builder.append(cons.head);
1832                 if (cons.tail.isEvaluated()) {
1833                     stream = stream.tail();
1834                     if (!stream.isEmpty()) {
1835                         builder.append(", ");
1836                     }
1837                 } else {
1838                     builder.append(", ?");
1839                     stream = null;
1840                 }
1841             }
1842             return builder.append(")").toString();
1843         }
1844     }
1845 }
1846 
1847 interface StreamModule {
1848 
1849     final class ConsImpl<T> extends Cons<T> implements Serializable {
1850 
1851         private static final long serialVersionUID = 1L;
1852 
1853         ConsImpl(T head, Supplier<Stream<T>> tail) {
1854             super(head, tail);
1855         }
1856 
1857         @Override
1858         public Stream<T> tail() {
1859             return tail.get();
1860         }
1861 
1862         @GwtIncompatible("The Java serialization protocol is explicitly not supported")
1863         private Object writeReplace() {
1864             return new SerializationProxy<>(this);
1865         }
1866 
1867         @GwtIncompatible("The Java serialization protocol is explicitly not supported")
1868         private void readObject(ObjectInputStream stream) throws InvalidObjectException {
1869             throw new InvalidObjectException("Proxy required");
1870         }
1871     }
1872 
1873     final class AppendElements<T> extends Cons<T> implements Serializable {
1874 
1875         private static final long serialVersionUID = 1L;
1876 
1877         private final io.vavr.collection.Queue<T> queue;
1878 
1879         AppendElements(T head, io.vavr.collection.Queue<T> queue, Supplier<Stream<T>> tail) {
1880             super(head, tail);
1881             this.queue = queue;
1882         }
1883 
1884         @Override
1885         public Stream<T> append(T element) {
1886             return new AppendElements<>(head, queue.append(element), tail);
1887         }
1888 
1889         @Override
1890         public Stream<T> appendAll(Iterable<? extends T> elements) {
1891             Objects.requireNonNull(elements, "elements is null");
1892             return isEmpty() ? Stream.ofAll(queue) : new AppendElements<>(head, queue.appendAll(elements), tail);
1893         }
1894 
1895         @Override
1896         public Stream<T> tail() {
1897             final Stream<T> t = tail.get();
1898             if (t.isEmpty()) {
1899                 return Stream.ofAll(queue);
1900             } else {
1901                 if (t instanceof ConsImpl) {
1902                     final ConsImpl<T> c = (ConsImpl<T>) t;
1903                     return new AppendElements<>(c.head(), queue, c.tail);
1904                 } else {
1905                     final AppendElements<T> a = (AppendElements<T>) t;
1906                     return new AppendElements<>(a.head(), a.queue.appendAll(queue), a.tail);
1907                 }
1908             }
1909         }
1910 
1911         @GwtIncompatible("The Java serialization protocol is explicitly not supported")
1912         private Object writeReplace() {
1913             return new SerializationProxy<>(this);
1914         }
1915 
1916         @GwtIncompatible("The Java serialization protocol is explicitly not supported")
1917         private void readObject(ObjectInputStream stream) throws InvalidObjectException {
1918             throw new InvalidObjectException("Proxy required");
1919         }
1920     }
1921 
1922     /**
1923      * A serialization proxy which, in this context, is used to deserialize immutable, linked Streams with final
1924      * instance fields.
1925      *
1926      * @param <T> The component type of the underlying stream.
1927      */
1928     // DEV NOTE: The serialization proxy pattern is not compatible with non-final, i.e. extendable,
1929     // classes. Also, it may not be compatible with circular object graphs.
1930     @GwtIncompatible("The Java serialization protocol is explicitly not supported")
1931     final class SerializationProxy<T> implements Serializable {
1932 
1933         private static final long serialVersionUID = 1L;
1934 
1935         // the instance to be serialized/deserialized
1936         private transient Cons<T> stream;
1937 
1938         /**
1939          * Constructor for the case of serialization.
1940          * <p>
1941          * The constructor of a SerializationProxy takes an argument that concisely represents the logical state of
1942          * an instance of the enclosing class.
1943          *
1944          * @param stream a Cons
1945          */
1946         SerializationProxy(Cons<T> stream) {
1947             this.stream = stream;
1948         }
1949 
1950         /**
1951          * Write an object to a serialization stream.
1952          *
1953          * @param s An object serialization stream.
1954          * @throws java.io.IOException If an error occurs writing to the stream.
1955          */
1956         private void writeObject(ObjectOutputStream s) throws IOException {
1957             s.defaultWriteObject();
1958             s.writeInt(stream.length());
1959             for (Stream<T> l = stream; !l.isEmpty(); l = l.tail()) {
1960                 s.writeObject(l.head());
1961             }
1962         }
1963 
1964         /**
1965          * Read an object from a deserialization stream.
1966          *
1967          * @param s An object deserialization stream.
1968          * @throws ClassNotFoundException If the object's class read from the stream cannot be found.
1969          * @throws InvalidObjectException If the stream contains no stream elements.
1970          * @throws IOException            If an error occurs reading from the stream.
1971          */
1972         private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
1973             s.defaultReadObject();
1974             final int size = s.readInt();
1975             if (size <= 0) {
1976                 throw new InvalidObjectException("No elements");
1977             }
1978             Stream<T> temp = Empty.instance();
1979             for (int i = 0; i < size; i++) {
1980                 @SuppressWarnings("unchecked")
1981                 final T element = (T) s.readObject();
1982                 temp = temp.append(element);
1983             }
1984             // DEV-NOTE: Cons is deserialized
1985             stream = (Cons<T>) temp;
1986         }
1987 
1988         /**
1989          * {@code readResolve} method for the serialization proxy pattern.
1990          * <p>
1991          * Returns a logically equivalent instance of the enclosing class. The presence of this method causes the
1992          * serialization system to translate the serialization proxy back into an instance of the enclosing class
1993          * upon deserialization.
1994          *
1995          * @return A deserialized instance of the enclosing class.
1996          */
1997         private Object readResolve() {
1998             return stream;
1999         }
2000     }
2001 
2002     final class AppendSelf<T> {
2003 
2004         private final Cons<T> self;
2005 
2006         AppendSelf(Cons<T> self, Function<? super Stream<T>, ? extends Stream<T>> mapper) {
2007             this.self = appendAll(self, mapper);
2008         }
2009 
2010         private Cons<T> appendAll(Cons<T> stream, Function<? super Stream<T>, ? extends Stream<T>> mapper) {
2011             return (Cons<T>) Stream.cons(stream.head(), () -> {
2012                 final Stream<T> tail = stream.tail();
2013                 return tail.isEmpty() ? mapper.apply(self) : appendAll((Cons<T>) tail, mapper);
2014             });
2015         }
2016 
2017         Cons<T> stream() {
2018             return self;
2019         }
2020     }
2021 
2022     interface Combinations {
2023 
2024         static <T> Stream<Stream<T>> apply(Stream<T> elements, int k) {
2025             if (k == 0) {
2026                 return Stream.of(Stream.empty());
2027             } else {
2028                 return elements.zipWithIndex().flatMap(
2029                         t -> apply(elements.drop(t._2 + 1), (k - 1)).map((Stream<T> c) -> c.prepend(t._1))
2030                 );
2031             }
2032         }
2033     }
2034 
2035     interface DropRight {
2036 
2037         // works with infinite streams by buffering elements
2038         static <T> Stream<T> apply(io.vavr.collection.List<T> front, io.vavr.collection.List<T> rear, Stream<T> remaining) {
2039             if (remaining.isEmpty()) {
2040                 return remaining;
2041             } else if (front.isEmpty()) {
2042                 return apply(rear.reverse(), io.vavr.collection.List.empty(), remaining);
2043             } else {
2044                 return Stream.cons(front.head(),
2045                         () -> apply(front.tail(), rear.prepend(remaining.head()), remaining.tail()));
2046             }
2047         }
2048     }
2049 
2050     interface StreamFactory {
2051 
2052         static <T> Stream<T> create(java.util.Iterator<? extends T> iterator) {
2053             return iterator.hasNext() ? Stream.cons(iterator.next(), () -> create(iterator)) : Empty.instance();
2054         }
2055     }
2056 
2057     final class StreamIterator<T> extends AbstractIterator<T> {
2058 
2059         private Supplier<Stream<T>> current;
2060 
2061         StreamIterator(Cons<T> stream) {
2062             this.current = () -> stream;
2063         }
2064 
2065         @Override
2066         public boolean hasNext() {
2067             return !current.get().isEmpty();
2068         }
2069 
2070         @Override
2071         public T getNext() {
2072             final Stream<T> stream = current.get();
2073             // DEV-NOTE: we make the stream even more lazy because the next head must not be evaluated on hasNext()
2074             current = stream::tail;
2075             return stream.head();
2076         }
2077     }
2078 }